package com.atstudy.selector;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
 * @version v1.0
 * @description:
 * @author: admin
 * @date: 2022/12/30 15:40
 * @copyright: 博为峰
 */
public class SocketChannelDemo {
    public static void main(String[] args) throws IOException {
        //创建客户端对象
        SocketChannel socketChannel = SocketChannel.open();
        //设置非阻塞
        socketChannel.configureBlocking(false);
        //连接服务器
        socketChannel.connect(new InetSocketAddress("127.0.0.1", 8080));
        //创建selector多路复用器
        Selector selector = Selector.open();
        //注册到selector多路复用器，设置连接事件
        socketChannel.register(selector, SelectionKey.OP_CONNECT);
        while (true) {
            //监听所有注册到selector上的事件
            int select = selector.select();
            if (select == 0) {
                continue;
            }
            //获取所有可用的
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            while (iterator.hasNext()) {
                //获取其中一个可用
                SelectionKey selectionKey = iterator.next();
                //从set集合中删除当前selectionKey
                iterator.remove();
                //Connect状态的Channel
                if (selectionKey.isConnectable()) {
                    HandleConnect(socketChannel, selector);
                    //Read状态的Channel
                } else if (selectionKey.isReadable()) {
                    HandleRead(socketChannel, selector);
                }
            }
        }
    }

    public static void HandleRead(SocketChannel socketChannel, Selector selector) throws IOException {
        System.out.println("服务器端向客户端发数据了");
        //字节缓冲区
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        int len = socketChannel.read(byteBuffer);
        if (len != -1)
            System.out.println(new String(byteBuffer.array(), 0, len));

    }

    public static void HandleConnect(SocketChannel socketChannel, Selector selector) throws IOException {
        //正在连接
        if(socketChannel.isConnectionPending()){
            //完成连接
            socketChannel.finishConnect();
            System.out.println("已经和服务器建立了连接");
            //设置非阻塞
            socketChannel.configureBlocking(false);
            //写数据到服务器
            ByteBuffer buffer = ByteBuffer.wrap("hello serve".getBytes());
            socketChannel.write(buffer);
            socketChannel.register(selector, SelectionKey.OP_READ);
        }
    }
}
